<?php
/**
 * Created by PhpStorm.
 * User: varcher
 * Date: 2017/12/30
 * Time: 下午10:06
 */

class GiallarWeOA extends Giallar
{
    private $corpTokenAccess    =   null;
    private $corpTokenCorpID    =   null;
    private $corpTokenSecret    =   null;
    private $agentID            =   null;
    private $redisTokenName     =   null;

    public function initialize($inputTokenCorpID, $inputTokenSecret, $inputAgentID, $inputRedisTokenName = "WeChatCorp_Token"): void
    {
        $this->corpTokenCorpID  =   $inputTokenCorpID;
        $this->corpTokenSecret  =   $inputTokenSecret;
        $this->redisTokenName = $inputRedisTokenName;
        $this->getToken();
        $this->agentID = $inputAgentID;
        return;
    }

    public function send(string $sendMessage, string $sendSubject, string $sendReceiver)
    {
        Yii::info("WeChat Message Sending, subject is {$sendSubject}");
        if (!$this->weOASend($sendMessage, $sendSubject, $sendReceiver)) {
            $this->sc_send($sendMessage);
        };
    }

    private function getToken():bool
    {
        $redis  =   Yii::$app->redis;
        if(is_null($accessToken = $redis->get($this->redisTokenName)))
        {
            $curlHandler = curl_init();

            $requireURL	=	"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$this->corpTokenCorpID}&corpsecret={$this->corpTokenSecret}";
            curl_setopt($curlHandler, CURLOPT_URL,            $requireURL);
            curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curlHandler, CURLOPT_HEADER,         false);
            curl_setopt($curlHandler, CURLOPT_TIMEOUT, 	       30);
            curl_setopt($curlHandler,CURLOPT_SSL_VERIFYPEER,false); ;
            curl_setopt($curlHandler, CURLOPT_FOLLOWLOCATION, true);

            $output = curl_exec($curlHandler);
            curl_close($curlHandler);

            //todo: 错误码判断
            if("" != $output)
            {
                $accessToken    =   json_decode($output) ->access_token;
                Yii::info("Get Corp WeChat ACCESS_TOKEN is: {$accessToken}");
                $redis->setex($this->redisTokenName, __WECHAT_ONE_HOUR_SECONDS__, $accessToken);
            }
            else {
                Yii::error("Get Corp WeChat ACCESS_TOKEN Failed!");
                return false;
            }
        }
        $this->corpTokenAccess = $accessToken;
        return true;
    }

    private function regetToken():bool
    {
        $redis  =   Yii::$app->redis;
        $redis  ->  del($this->redisTokenName);
        return $this->getToken();
    }

    /**
     * @param string $sendMessage
     * @param string $sendSubject
     * @param string $sendReceiver
     * @return bool
     */
    private function weOASend(string $sendMessage, string $sendSubject, string $sendReceiver):bool
    {
        $sendInfo	=	array(	'touser' 		=> $sendReceiver,
            'toparty'		=> "",
            'totag'			=> "",
            'msgtype'		=> "text",
            'agentid'		=> $this->agentID,
            'text'			=> array('content' => $sendSubject."\n".$sendMessage),
            'safe'			=> 0);
        $sendingMessage = json_encode($sendInfo);

        $curlHandler = curl_init();
        do {
            $repeatSend	=	false;
            curl_setopt($curlHandler, CURLOPT_URL, "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={$this->corpTokenAccess}");
            curl_setopt($curlHandler, CURLOPT_TIMEOUT, 30);
            curl_setopt($curlHandler, CURLOPT_CONNECTTIMEOUT, 30);
            curl_setopt($curlHandler, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书

            curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curlHandler, CURLOPT_POST, true);
            curl_setopt($curlHandler, CURLOPT_POSTFIELDS, $sendingMessage);
            $ret = curl_exec($curlHandler);
            $ret_decode = json_decode($ret, true);

            if(!isset($ret_decode['errcode']))
            {
                $ret_decode['errcode']	=	__WECHAT_TOKEN_ERROR_INVALID__;
            }

            switch ($ret_decode['errcode']) {
                case __WECHAT_RETURN_SUCCESS__:
//                    Yii::info("Send successfully.");
                    $processStatus	=	true;
                    break;
                case __WECHAT_TOKEN_ERROR_EXPIRED__:
                case __WECHAT_TOKEN_ERROR_INVALID__:
                    Yii::warning("Corp WeChat Send temporary failed, return code = {$ret_decode['errcode']}, try to REGet ACCESS_TOKEN.");
                    $this->regetToken();
                    $repeatSend = true;
//				Logger::getLogger('wechat')->info("TOKEN EXPIRED, REFETCH TOKEN.");
                    break;
                default:
                    Yii::error("Corp WeChat Send failed, return code = {$ret_decode['errcode']}.");
                    $processStatus =	false;
//				Logger::getLogger('wechat')->warn("CORP WECHAT SEND FAILED, RC = ".json_decode($ret)->errcode);
                    break;
            }

        } while ($repeatSend);
        curl_close($curlHandler);

        return $processStatus;
    }

    private function sc_send($desp, $text = '大事不妙', $key = __MESSENGER_WECHAT_FCQQ_TOKEN__)
    {
        $postdata = http_build_query(
            array(
                'text' => $text,
                'desp' => $desp
            )
        );

        $opts = array('http' =>
            array(
                'method'  => 'POST',
                'header'  => 'Content-type: application/x-www-form-urlencoded',
                'content' => $postdata
            )
        );
        $context  = stream_context_create($opts);
        return $result = file_get_contents('https://sc.ftqq.com/'.$key.'.send', false, $context);
    }
}